import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:multi_image_picker/multi_image_picker.dart';
import 'package:provider/provider.dart';
import 'package:qunaimedical/components/custom_divider.dart';
import 'package:qunaimedical/components/edit_text_field.dart';
import 'package:qunaimedical/components/item_add.dart';
import 'package:qunaimedical/components/item_image_preview.dart';
import 'package:qunaimedical/components/item_option.dart';
import 'package:qunaimedical/components/primary_button.dart';
import 'package:qunaimedical/components/primary_label.dart';
import 'package:qunaimedical/init/provider.dart';
import 'package:qunaimedical/models/area.dart';
import 'package:qunaimedical/models/department.dart';
import 'package:qunaimedical/models/doctor_account.dart';
import 'package:qunaimedical/models/hospital.dart';
import 'package:qunaimedical/models/list_response.dart';
import 'package:qunaimedical/models/professional.dart';
import 'package:qunaimedical/models/user.dart';
import 'package:qunaimedical/models/user_post_bean.dart';
import 'package:qunaimedical/network/http.dart';
import 'package:qunaimedical/pages/field_edit.dart';
import 'package:qunaimedical/pages/home.dart';
import 'package:qunaimedical/utils/common_util.dart';
import 'package:qunaimedical/utils/dialog_utils.dart';
import 'package:qunaimedical/utils/log_utils.dart';
import 'package:qunaimedical/utils/toast_util.dart';
import 'package:qunaimedical/values/urls.dart';
import 'package:sprintf/sprintf.dart';

/// 资质认证
class AuthPage extends StatefulWidget {
  static const String routeName = '/auth';

  @override
  _AuthPageState createState() => _AuthPageState();
}

class _AuthPageState extends State<AuthPage> {
  static String _tag = '_AuthPageState';
  TextEditingController _skillController = TextEditingController();
  FocusNode _focus = FocusNode();

  /// 选中的图片
  List<Asset> _images = <Asset>[];

  /// 选中的身份图片
  List<Asset> _cardImages = <Asset>[];

  /// 最多选5张图片
  int maxImageCount = 5;

  /// 用户上传的图片路径
  List<String> _uploadedImages = [];

  /// 用户上传的图片路径
  List<String> _uploadedCardImages = [];

  /// 待提交用户信息
  UserPostBean bean;

  /// 医院列表
  List<Hospital> _hospitalList = [];

  /// 科室列表。
  List<Department> _departments = [];

  /// 职称列表
  List<Professional> _professionalTypes = [];

  /// 地区id
  String _areaId;

  @override
  Widget build(BuildContext context) {
    User user = context.watch<StoreInfo>().user;
    Map<String, String> genderMap = {'': '未知', '0': '女', '1': '男'};
    return Scaffold(
      appBar: AppBar(title: Text('资质认证')),
      body: ListView(
        children: [
          CustomDivider(),
          PrimaryLabel('个人信息'),
          ItemOption(
            text: '手机号',
            secondText: user?.cellphone ?? '',
            hideRightArrow: true,
          ),
          ItemOption(
            text: '姓名',
            secondText: bean.fullname ?? '',
            onTap: _editName,
          ),
          ItemOption(
            text: '性别',
            secondText: genderMap[bean.sex ?? ''],
            onTap: _selectGender,
          ),
          ItemOption(
            text: '单位所在地',
            secondText: bean.address ?? '',
            onTap: () {
              _focus.unfocus();
              DialogUtils.showSelectCityDialog(context).then((value) {
                if (value != null) {
                  setState(() {
                    bean.address = value[0].toString();
                    _areaId = (value[1] as Area).id;
                    // 选择所在地后，重置医院显示。
                    bean.info.hospitalId = null;
                  });
                  _fetchHospitalList();
                }
              });
            },
          ),
          ItemOption(
            text: '医院',
            secondText: bean.info.hospitalId == null || _hospitalList.isEmpty
                ? ''
                : _hospitalList
                    .firstWhere(
                        (element) => element.hospitalId == bean.info.hospitalId)
                    .hospitalName,
            onTap: _selectHospital,
          ),
          ItemOption(
            text: '科室',
            secondText: bean.info.sectionName ?? '',
            onTap: _selectDepartment,
          ),
          ItemOption(
            text: '职称',
            secondText: bean.info.professionalName ?? '',
            onTap: _selectProfessional,
          ),
          ItemOption(
            text: '从业年限',
            secondText: bean.info.caree ?? '',
            onTap: _editYears,
          ),
          ItemOption(
            text: '身份证号',
            secondText: bean.idcard ?? '',
            onTap: _editIdCard,
          ),
          CustomDivider(),
          PrimaryLabel('擅长领域'),
          EditTextField(
            maxLines: 5,
            maxLength: 400,
            hintText: '请输入您擅长的领域',
            controller: _skillController,
            focusNode: _focus,
          ),
          CustomDivider(),
          PrimaryLabel(
            '职业证书',
            trailing: Text('${_images.length}/$maxImageCount'),
          ),
          Container(
            height: 110,
            color: Colors.white,
            width: double.maxFinite,
            alignment: Alignment.topLeft,
            padding: EdgeInsets.all(10),
            child: ListView.separated(
              scrollDirection: Axis.horizontal,
              itemBuilder: (c, i) {
                if (i == _images.length) {
                  return ItemAdd(onTap: _selectImages);
                } else {
                  return ItemImagePreview(
                    _images[i],
                    onTap: () {
                      // 删除图片时，判断已上传图片列表中是否包含这张照片。
                      if (_uploadedImages.length > i) {
                        _uploadedImages.removeAt(i);
                      }
                      setState(() {
                        _images.removeAt(i);
                      });
                    },
                  );
                }
              },
              itemCount: _images.length == maxImageCount
                  ? _images.length
                  : _images.length + 1,
              padding: EdgeInsets.only(left: 0),
              separatorBuilder: (BuildContext context, int index) {
                // 给最后一个加号前面添加间距。
                return SizedBox(
                  width: _images.length > 0 && index == _images.length - 1
                      ? 13
                      : 0,
                );
              },
            ),
          ),
          Container(
            color: Colors.white,
            padding: EdgeInsets.only(left: 16, right: 16, bottom: 16),
            child: Text(
              '请上传带有职业医院名称的职业证书，证书内容不得有遮挡。',
              style: Theme.of(context).textTheme.caption,
            ),
          ),
          CustomDivider(),
          PrimaryLabel(
            '身份证照片',
            trailing: Text('${_images.length}/2'),
          ),
          Container(
            height: 110,
            color: Colors.white,
            width: double.maxFinite,
            alignment: Alignment.topLeft,
            padding: EdgeInsets.all(10),
            child: ListView.separated(
              scrollDirection: Axis.horizontal,
              itemBuilder: (c, i) {
                if (i == _cardImages.length) {
                  return ItemAdd(onTap: () => _selectImages(index: 1));
                } else {
                  return ItemImagePreview(
                    _cardImages[i],
                    onTap: () {
                      // 删除图片时，判断已上传图片列表中是否包含这张照片。
                      if (_uploadedCardImages.length > i) {
                        _uploadedCardImages.removeAt(i);
                      }
                      setState(() {
                        _cardImages.removeAt(i);
                      });
                    },
                  );
                }
              },
              itemCount: _cardImages.length == 2
                  ? _cardImages.length
                  : _cardImages.length + 1,
              padding: EdgeInsets.only(left: 0),
              separatorBuilder: (BuildContext context, int index) {
                // 给最后一个加号前面添加间距。
                return SizedBox(
                  width:
                      _cardImages.length > 0 && index == _cardImages.length - 1
                          ? 13
                          : 0,
                );
              },
            ),
          ),
          Container(
            color: Colors.white,
            padding: EdgeInsets.only(left: 16, right: 16, bottom: 16),
            child: Text(
              '请上传身份证正反面照片。',
              style: Theme.of(context).textTheme.caption,
            ),
          ),
          PrimaryButton(
            '提交',
            onPressed: _auth,
          )
        ],
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _skillController.dispose();
  }

  @override
  void initState() {
    super.initState();
    var user = context.read<StoreInfo>().user;
    Log.d(_tag, 'user: $user');
    bean = UserPostBean(
      id: user.id,
      fullname: user.fullname,
      sex: user.sex,
      address: user.address,
      info: DoctorInfo(
        sectionName: user.sectionName,
        professionalName: user.professionalName,
        professionalLevel: user.professionalLevel,
      ),
    );
    _skillController.text = user.skilled;
    _fetchHospitalList();
    _fetchDepartmentTypes();
    _fetchProfessionalTypes();
  }

  /// 进行认证
  void _auth() async {
    _focus.unfocus();
    if (_uploadedImages.isNotEmpty) {
      bean.image = _uploadedImages.join(',');
    }
    if (_uploadedCardImages.isNotEmpty) {
      bean.idcardImage = _uploadedCardImages.join(',');
    }
    if (_skillController.text.trim().isNotEmpty) {
      bean.info.skilled = _skillController.text.trim();
    }
    DialogUtils.showWaitDialog(context);
    var data = await XHttp.postJson(Urls.DOCTOR_INFO_UPDATE, bean.toMap());
    Navigator.pop(context);
    if (data != null && data is Map<String, dynamic>) {
      if (data['code'] == 1) {
        Navigator.popUntil(context, ModalRoute.withName(HomePage.routeName));
      } else {
        ToastUtil.show(data['msg'], context);
      }
    }
  }

  void _editName() {
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (c) => FieldEditPage(
          type: FieldEditType.name,
          value: bean.fullname,
        ),
      ),
    ).then((value) {
      Log.d(_tag, value);
      if (value != null) {
        setState(() {
          bean.fullname = value;
        });
      }
    });
  }

  void _selectGender() {
    _focus.unfocus();
    DialogUtils.showSelectOptionDialog(context, '选择性别', ['女', '男'])
        .then((value) {
      Log.d(_tag, value);
      if (value != null) {
        setState(() {
          bean.sex = value.toString();
        });
      }
    });
  }

  void _selectHospital() {
    _focus.unfocus();
    DialogUtils.showSelectOptionDialog(
            context, '选择医院', _hospitalList.map((e) => e.hospitalName).toList())
        .then((value) {
      if (value != null) {
        setState(() {
          bean.info.hospitalId = _hospitalList[value].hospitalId;
        });
      }
    });
  }

  void _selectDepartment() {
    _focus.unfocus();
    DialogUtils.showSelectOptionDialog(
            context, '选择科室', _departments.map((e) => e.label).toList())
        .then((value) {
      Log.d(_tag, value);
      if (value != null) {
        setState(() {
          bean.info.sectionType = _departments[value].value;
          bean.info.sectionName = _departments[value].label;
        });
      }
    });
  }

  void _selectProfessional() {
    _focus.unfocus();
    DialogUtils.showSelectOptionDialog(
            context, '选择职级', _professionalTypes.map((e) => e.label).toList())
        .then((value) {
      Log.d(_tag, value);
      if (value != null) {
        setState(() {
          bean.info.professionalLevel = _professionalTypes[value].value;
          bean.info.professionalName = _professionalTypes[value].label;
        });
      }
    });
  }

  void _selectImages({int index = 0}) async {
    _focus.unfocus();
    try {
      List<Asset> value = await MultiImagePicker.pickImages(
        maxImages: maxImageCount,
        selectedAssets: index == 0 ? _images : _cardImages,
      );
      if (mounted) {
        setState(() {
          if (index == 0) {
            _images = value;
          } else {
            _cardImages = value;
          }
        });
        if (index == 0) {
          if (_images.isNotEmpty) {
            _uploadImages();
          }
        } else {
          if (_cardImages.isNotEmpty) {
            _uploadIdcardImages();
          }
        }
      }
    } on Exception catch (e) {
      Log.d(_tag, e);
    }
  }

  /// 图片上传
  void _uploadImages() async {
    DialogUtils.showWaitDialog(context);
    FormData formData = FormData.fromMap({});
    formData.files.addAll((await CommonUtils.images2MapEntry(_images)));
    var value = await XHttp.uploadFiles(
      Urls.UPLOAD,
      formData,
    );
    Navigator.pop(context);
    if (value != null) {
      ListResponse response = ListResponse.fromJson(value);
      if (response.code == 1) {
        _uploadedImages = List<String>.from(response.data);
      }
    }
  }

  /// 身份证图片上传
  void _uploadIdcardImages() async {
    DialogUtils.showWaitDialog(context);
    FormData formData = FormData.fromMap({});
    formData.files.addAll((await CommonUtils.images2MapEntry(_cardImages)));
    var value = await XHttp.uploadFiles(
      Urls.UPLOAD,
      formData,
    );
    Navigator.pop(context);
    if (value != null) {
      ListResponse response = ListResponse.fromJson(value);
      if (response.code == 1) {
        _uploadedCardImages = List<String>.from(response.data);
      }
    }
  }

  void _fetchHospitalList() async {
    Map<String, dynamic> params = {};
    if (_areaId != null && _areaId != '') {
      params['areaId'] = _areaId;
    }
    var value = await XHttp.postJson(Urls.HOSPITAL_LIST, params);
    if (value != null) {
      ListResponse response = ListResponse.fromJson(value);
      if (response.code == 1) {
        _hospitalList =
            List.from(response.data.map((e) => Hospital.fromJson(e)));
      } else {
        ToastUtil.show(response.msg, context);
      }
    }
  }

  /// 获取科室列表
  void _fetchDepartmentTypes() async {
    var data =
        await XHttp.postJson(sprintf(Urls.DICT_VALUES, ['section_type']));
    if (data != null) {
      ListResponse response = ListResponse.fromJson(data);
      if (response.code == 1) {
        if (mounted) {
          _departments =
              List.from(response.data.map((e) => Department.fromJson(e)));
        }
      }
    }
  }

  void _fetchProfessionalTypes() async {
    var data =
        await XHttp.postJson(sprintf(Urls.DICT_VALUES, ['technical_title']));
    if (data != null) {
      ListResponse response = ListResponse.fromJson(data);
      if (response.code == 1) {
        if (mounted) {
          var list = List<Professional>.from(
              response.data.map((e) => Professional.fromJson(e)));
          list.sort((a, b) => a.sort.compareTo(b.sort));
          _professionalTypes = list;
          Log.i(_professionalTypes);
        }
      }
    }
  }

  void _editYears() {
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (c) => FieldEditPage(
          type: FieldEditType.years,
          value: bean.info.caree,
        ),
      ),
    ).then((value) {
      Log.d(_tag, value);
      if (value != null) {
        setState(() {
          bean.info.caree = value.toString();
        });
      }
    });
  }

  void _editIdCard() {
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (c) => FieldEditPage(
          type: FieldEditType.idcard,
          value: bean.idcard,
        ),
      ),
    ).then((value) {
      Log.d(_tag, value);
      if (value != null) {
        setState(() {
          bean.idcard = value.toString();
        });
      }
    });
  }
}
